﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;

using OrandoLabs.Common;
using OrandoLabs.EnduroStore;
using OrandoLabs.CojectoSemantic;

namespace OrandoLabs.OpenSource.Cojecto
{
    public class CojectoBulkLoader
    {
        OrandoInstance Instance;
        EnduroInstance EInstance;
        protected EnduroDatabase EDb;
        CojectoSemanticDatabase Db;
        
        public CojectoBulkLoader(String name, String dir)
        {
            Instance = new OrandoInstance(name, dir);
            float maxCache = (float) (3.0 * 1024 *1024 * 1024); //3G on this crappy box
            Instance.SetCacheSizeMax(maxCache);
            EInstance = new EnduroInstance(Instance);
            EDb = new EnduroDatabase(EInstance, name + ".edb");
            Db = new CojectoSemanticDatabase(name, EDb);
        }

        public void Dispose()
        {
            Instance.Dispose();
        }

    }

    public class CojectoBulkFolderLoader : CojectoBulkLoader
    {
        String Name;
        String Folder;
        String BaseUri;
        public CojectoBulkFolderLoader(String name, String dir, String folder, String baseUri)
            : base(name, dir)
        {
            Name = name;
            Folder = folder;
            BaseUri = baseUri;
        }

        public async Task<bool> Load(Func<string,bool,bool> fileProgress, Func<long, long, bool> triplesProgress)
        {
            long total = 0;
            long triples = 0;
            return await Task<bool>.Run(() =>
                {
                    using (CojectoSemanticSession sess = new CojectoSemanticSession(Name, EDb, true))
                    {
                        sess.AddStatementCallback = ((S, P, O, C, Type, Language, Datatype) =>
                            {
                                total++;
                                triples++;
                                triplesProgress(triples, total);
                            }
                        );
                        string[] files = Directory.GetFiles(Folder);
                        for (int i = 0; i < files.Length; i++)
                        {
                            triples = 0;
                            String file = files[i];
                            if (!file.EndsWith(".nt")) continue;
                            if (!fileProgress(file, true)) break;
                            sess.LoadNtFile(file, BaseUri);
                            if (!fileProgress(file,false)) break;
                        }
                        sess.BulkLoadDone();
                    }
                    return true;
                }
            );
        }
    }

}